Thursday, 30 October 2014

Capturing Scala profile data from the command line

Sometimes it's just not practical to attach a profiler to a running application. For instance you may want to profile your application's startup code.

If you're using Oracle's JDK you can solve this problem with command line parameters which start Java Flight Recorder as your application starts up. The available parameters are somewhat byzantine so it's worth your time to read the command line documentation

As an example, I use the VM parameters below when I want to profile an integration test from inside IntelliJ:

-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=defaultrecording=true -XX:FlightRecorderOptions=dumponexit=true,dumponexitpath=/Some/Folder

If you use these parameters a .jfr file containing profile data will be written to /Some/Folder when your application exits. You can then open the file with Java Mission Control.

If .jfr file associations aren't set up you can launch Java Mission Control on a Mac from /usr/bin/jmc.

This is what it looks like - not bad for a tool which is free to use!

Tools for profiling your Scala app

One of the neat things about Scala (and other JVM languages) is that the JDK comes bundled with free profilers.

Both Oracle's JDK and OpenJDK are bundled with the open source Java VisualVM profiler.

Oracle's JDK also comes bundled with Java Mission Control which is free to use on development machines (even though it is a commercial product).

To my eye Java Mission Control seems a better choice in a lot of cases. Having said that each tools has different capabilities.

For details on when to use each profiler, what other tools are available if neither profiler solves your problem, and the commercial license for Java Mission Control take a look at Oracle's Diagnostic Tools and Detailed Descriptions page.

Wednesday, 3 September 2014

Using Scala's FiniteDuration DSL

As a relatively new Scala developer I often find myself hunting for the the correct imports to enable various implicit conversions. A particularly useful set of implicit conversions are those that convert an Int / Long / Double to a FiniteDuration. They allow you to write code like:
val timeout1 = 3 seconds
val timeout2 = 3.5 minutes
To enable this syntax you need to import one or more of the following:
import scala.concurrent.duration.{DurationInt, DurationLong, DurationDouble}